Podsumowanie

(poniższe komentarze dostępne są również w miejscu ich dotyczącym)

a.d.3. Kod pozwalający wczytać dane z pliku.

Do wczytania danych wykorzystałem funkcję fread z pakietu data.table. Funkcja ta jest znacznie szybsza niż read.table i pozwala na usuwanie zbędnych kolumn już na etapie wczytywania danych. Dodatkowo prawidłowo rozpoznaje kolumny o typie Integer

a.d.5. Kod przetwarzający brakujące dane.

Dane zostają podzielone na 3 części (part_00, part_01 i part_02). Prefisky kolumn usunięte, dodana kolumna part z wartością odpowiedniego partu będącego źródłem danych. Następnie dane są łączone w jeden data frame. Proces ten usuwa wszystkie wartości NA - uzyskane dane są więc wyczyszczone.

Jeżeli any_meas* = 0, to zakładam, że nie nastąpił‚ pomiar (w kolejnych kolumnach dane NA, gdyż nie było podstawy do obliczeń). W takiej sytuacji zamiana NA na np. średnią nie ma sensu (0 elektronów nie może mieć kształtu itp.) dlatego też dane dotyczące danego part zostają usunięte.

*any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) [żadna z tych zmiennych nie przyjmuje wartości < 0, więc suma == 0 jednoznacznie wskazuje na brak tych danych]

a.d.8. Sekcję sprawdzającą korelacje między zmiennymi

Poniżej znajduje się wykres korelacji między zmiennymi. Zauważyć można, że:

  • Duża część zmiennych jest w silnej korelacji z innymi zmiennymi

  • Zmienne density_Z* i shape_z* są w bardzo silnej korelacji (duże czerwone prostokąty)

  • Zmienne local* korelują z zmiennymi z part (były obliczane na ich podstawie)

a.d.14 i 15

Spośród testowanych metod najlepiej sprawdziły się:

  • Linear Regression (lm) dla regresji

  • Random Forest (rf) dla klasyfikacji

Z racji dużego zbioru danych (ok. 1 mln rekordów) za metodę wybierania zbioru walidacyjnego wybrałem bootstrap (losowanie ze zwracaniem) - metoda zapewnia stratyfikację danych (https://machinelearningmastery.com/how-to-estimate-model-accuracy-in-r-using-the-caret-package/)

a.d.14.Sekcję sprawdzającą czy na podstawie wartości innych kolumn można przewidzieć:

Na podstawie obliczeń usatliłem, że odpowiednio 3% i 1% danych powinien wystarczyć jako zbiór testowy (z obliczeniami można zapoznać się w sekcji 14)

Liczba elektronów została określona z miarami:

RMSE = 64,453

r^2 = 0,48

Liczba elektronów została określona z miarami:

RMSE = 9,45

r^2 = 0,49

a.d.15.Sekcję próbującą stworzyć klasyfikator przewidujący wartość atrybutu res_name

Na podstawie obliczeń usatliłem, że 1% danych powinien wystarczyć jako zbiór testowy (z obliczeniami można zapoznać się w sekcji 15)

Random Forest uzyskał precyzję = 0,6

Klasyfikator naiwny (wskazujący najliczniejszą klasę) dokonałby predykcji res_name = SO4. Miara Accuracy = 0,15.

1. Kod wyliczający wykorzystane biblioteki.

library(data.table)
library(DT)
library(ggplot2)
library(plotly)
library(dplyr)
library(reshape)
library(caret)

2. Kod zapewniający powtarzalność wyników.

set.seed(123)

3. Kod pozwalający wczytać dane z pliku.

Do wczytania danych wykorzystałem funkcję fread z pakietu data.table. Funkcja ta jest znacznie szybsza niż read.table i pozwala na usuwanie zbędnych kolumn już na etapie wczytywania danych. Dodatkowo prawidłowo rozpoznaje kolumny o typie Integer

out_columns <- c("blob_coverage", "res_coverage", "title", "pdb_code", "res_id", "chain_id", "blob_volume_coverage", "blob_volume_coverage_second", "res_volume_coverage", "res_volume_coverage_second", "skeleton_cycle_4", "skeleton_diameter", "skeleton_cycle_6", "skeleton_cycle_7", "skeleton_closeness_006_008", "skeleton_closeness_002_004", "skeleton_cycle_3", "skeleton_avg_degree", "skeleton_closeness_004_006", "skeleton_closeness_010_012", "skeleton_closeness_012_014", "skeleton_edges", "skeleton_radius", "skeleton_cycle_8_plus", "skeleton_closeness_020_030", "skeleton_deg_5_plus", "skeleton_closeness_016_018", "skeleton_closeness_008_010", "skeleton_closeness_018_020", "skeleton_average_clustering", "skeleton_closeness_040_050", "skeleton_closeness_014_016", "skeleton_center", "skeleton_closeness_000_002", "skeleton_density", "skeleton_closeness_030_040", "skeleton_deg_4", "skeleton_deg_0", "skeleton_deg_1", "skeleton_deg_2", "skeleton_deg_3", "skeleton_graph_clique_number", "skeleton_nodes", "skeleton_cycles", "skeleton_cycle_5", "skeleton_closeness_050_plus", "skeleton_periphery", "local_cut_by_mainchain_volume", "local_near_cut_count_C", "local_near_cut_count_other", "local_near_cut_count_S", "local_near_cut_count_O", "local_near_cut_count_N", "fo_col", "fc_col", "weight_col", "grid_space", "solvent_radius", "solvent_opening_radius", "resolution_max_limit", "part_step_FoFc_std_min", "part_step_FoFc_std_max", "part_step_FoFc_std_step", "skeleton_data", "local_res_atom_count", "local_res_atom_non_h_occupancy_sum", "local_res_atom_non_h_electron_occupancy_sum", "local_res_atom_C_count", "local_res_atom_N_count", "local_res_atom_O_count", "local_res_atom_S_count", "dict_atom_C_count", "dict_atom_N_count", "dict_atom_O_count", "dict_atom_S_count")

file = "C:/Users/Developer/Desktop/all_summary.csv"
data <- fread(file = file, 
             sep = ";", 
             header = TRUE,
             na.string = c(",,", "NAN", "nan"),
             drop = out_columns
            )

4. Kod usuwający z danych wiersze posiadające wartość zmiennej res_name

out_res_names = c("UNK", "UNX", "UNL", "DUM", "N", "BLOB", "ALA", "ARG", "ASN", "ASP", "CYS", "GLN", "GLU", "GLY", "HIS", "ILE", "LEU", "LYS", "MET", "MSE", "PHE", "PRO", "SEC", "SER", "THR", "TRP", "TYR", "VAL", "DA", "DG", "DT", "DC", "DU", "A", "G", "T", "C", "U", "HOH", "H20", "WAT")
data <- data %>% filter(!res_name %in% out_res_names)

5. Kod przetwarzający brakujące dane.

Dane zostają podzielone na 3 części (part_00, part_01 i part_02). Prefisky kolumn usunięte, dodana kolumna part z wartością odpowiedniego partu będącego źródłem danych. Następnie dane są łączone w jeden data frame. Proces ten usuwa wszystkie wartości NA - uzyskane dane są więc wyczyszczone.

Jeżeli any_meas* = 0, to zakładam, że nie nastąpił‚ pomiar (w kolejnych kolumnach dane NA, gdyż nie było podstawy do obliczeń). W takiej sytuacji zamiana NA na np. średnią nie ma sensu (0 elektronów nie może mieć kształtu itp.) dlatego też dane dotyczące danego part zostają usunięte.

*any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) [żadna z tych zmiennych nie przyjmuje wartości < 0, więc suma == 0 jednoznacznie wskazuje na brak tych danych]

data_part00 <- data %>% 
    select(-starts_with("part_01"), -starts_with("part_02")) %>% 
    rename_at(.vars = vars(starts_with("part_00_")), .funs = funs(sub("^part_00_", "", .))) %>%
    mutate(any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) %>%       
    filter(any_meas != 0) %>% 
    select(-any_meas) %>%
    mutate(part = "part_00")

data_part01 <- data %>% 
    select(-starts_with("part_00"), -starts_with("part_02")) %>% 
    rename_at(.vars = vars(starts_with("part_01_")), .funs = funs(sub("^part_01_", "", .))) %>%
    mutate(any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) %>%       
    filter(any_meas != 0) %>% 
    select(-any_meas) %>%  
    mutate(part = "part_01")

data_part02 <- data %>% 
    select(-starts_with("part_00"), -starts_with("part_01")) %>% 
    rename_at(.vars = vars(starts_with("part_02_")), .funs = funs(sub("^part_02_", "", .))) %>%
    mutate(any_meas = shape_segments_count + density_segments_count + volume + electrons + mean + std + max + max_over_std + skewness + parts) %>%       
    filter(any_meas != 0) %>% 
    select(-any_meas) %>%  
    mutate(part = "part_02")
data <- rbind(data_part00, data_part01, data_part02) 

W kolumnach znajduje się local_min - kolumna ta ma 0 we wszystkich wierszach - jest więc zbędna

data %>% select(local_min) %>% distinct()
##   local_min
## 1         0
data <- data %>% select(-local_min)
rm(data_part00, data_part01, data_part02)

6. Sekcję podsumowującą rozmiar zbioru i podstawowe statystyki.

Wymiary:

dim(data)
## [1] 1710450     125

Liczba unikalnych res_name

data %>% select(res_name) %>% distinct() %>% nrow()
## [1] 19603

Przykładów/part

data %>% group_by(part) %>% summarize(n = n()) %>% arrange(desc(n)) %>% prettyTable()

Podstawowe statystyki pozostałych kolumn

data %>% select(-res_name, -starts_with("part")) %>%
  summary() %>% 
  unclass() %>%
  data.frame(check.names = FALSE, stringsAsFactors = FALSE) %>% 
  prettyTable()

7. Kod ograniczający liczbę klas (res_name) do 50 najpopularniejszych wartości.

res_name50 <- data %>% group_by(res_name) %>% summarize(n = n()) %>% arrange(desc(n)) %>% head(50)
data <- data %>% filter(res_name %in% res_name50$res_name)
rm(res_name50)

8. Sekcję sprawdzającą korelacje między zmiennymi

Poniżej znajduje się wykres korelacji między zmiennymi. Zauważyć można, że: * Duża część zmiennych jest w silnej korelacji z innymi zmiennymi * Zmienne density_Z* i shape_z* są w bardzo silnej korelacji (duże czerwone prostokąty) * Zmienne local* korelują z zmiennymi z part (były obliczane na ich podstawie)

melted <- data %>% select(-res_name, -part) %>% cor() %>% melt
breaks <- sort(colnames(data))[seq(1, ncol(data), by = 6)]

(ggplot(data = melted, aes(x=X1, y=X2, fill=value)) + 
    theme(
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        axis.text.x = element_text(angle=45)
      ) + 
    scale_x_discrete(breaks = breaks) + 
    scale_y_discrete(breaks = breaks) + 
    geom_tile() +
    scale_fill_gradient2(
        low = "blue", high = "red", mid = "white", 
        midpoint = 0, limit = c(-1,1))
      ) %>%
   ggplotly()
rm(melted, breaks)

9. Określenie ile przykładów ma każda z klas.

data %>% select(res_name) %>% group_by(res_name) %>% summarize(n = n()) %>% arrange(desc(n)) %>% prettyTable()

10. Wykresy rozkładów liczby atomów i elektronów.

(ggplot(data, aes(local_res_atom_non_h_count, fill = "red")) + geom_bar() + theme_bw()) %>% ggplotly()
(ggplot(data, aes(local_res_atom_non_h_electron_sum, fill = "red")) + geom_bar(width = 3) + theme_bw()) %>% ggplotly()

11. Tabelę pokazującą 10 klas z największą niezgodnością liczby atomów i liczby elektronów

diff <- data %>% select(res_name, local_res_atom_non_h_count, dict_atom_non_h_count, local_res_atom_non_h_electron_sum, dict_atom_non_h_electron_sum) %>%
  group_by(res_name) %>% summarize(atom_diff = sum(abs(local_res_atom_non_h_count - dict_atom_non_h_count)), electron_diff = sum(abs(local_res_atom_non_h_electron_sum - dict_atom_non_h_electron_sum)))

diff %>% select(-electron_diff) %>% arrange(desc(atom_diff)) %>% head(10) %>% prettyTable()
diff %>% select(-atom_diff) %>% arrange(desc(electron_diff)) %>% head(10) %>% prettyTable()
rm(diff)

12. Sekcję pokazującą rozkład wartości part_01

melted <- data %>% filter(part == "part_01") %>% select(shape_segments_count:density_Z_4_0) %>% melt
means <-  melted %>% group_by(variable) %>% summarise(mean=mean(value)) 
melted %>% ggplot(aes(value)) +
    geom_density() +
    geom_vline(data = means, aes(xintercept=mean), linetype="dashed", color = "red") +
    geom_text(data=means, mapping=aes(x=mean, y=0, label=signif(mean, digits = 4)), 
              size=3, angle=90, vjust= 1, hjust=0, color = "red"
      )+  
    facet_wrap(~variable, ncol = 4, scales = "free") +
    theme_bw()+
    theme(
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        axis.text.x = element_text(angle=90)
      ) 

rm(melted, means)

13. Interaktywny wykres lub animację.

W pkt 8. i 10.

14.Sekcję sprawdzającą czy na podstawie wartości innych kolumn można przewidzieć:

liczbę elektronów

Posiadam ok 1mln przykładów podzielonych na n klas

n = data %>% select(local_res_atom_non_h_electron_sum) %>% distinct() %>% count()
n
## # A tibble: 1 x 1
##       n
##   <int>
## 1   176

Zbiór testowy złożony z 3% tych danych powinien być wystarczający. Każda z klas będzie miała więc ok. k przykładów (zależnie od rozkładu)

k = nrow(data) * 0.03 / n
k
##          n
## 1 190.3739
idx <- createDataPartition(data$local_res_atom_non_h_electron_sum, p=0.03, list=F, times = 1)
test <- data.frame(data[idx,]) %>% select(-res_name, -local_res_atom_non_h_count)
train <- data.frame(data[-idx,]) %>% select(-res_name, -local_res_atom_non_h_count)

ctrl <- trainControl(
    method = "boot", number = 20)
 
fit <- train(local_res_atom_non_h_electron_sum ~ .,
             data = train,
             method = "lm",
             trControl = ctrl,
             metric = "Rsquared",
             maximize = TRUE)

fit
## Linear Regression 
## 
## 1083352 samples
##     120 predictor
## 
## No pre-processing
## Resampling: Bootstrapped (20 reps) 
## Summary of sample sizes: 1083352, 1083352, 1083352, 1083352, 1083352, 1083352, ... 
## Resampling results:
## 
##   RMSE      Rsquared   MAE     
##   64.43256  0.4826822  36.23728
## 
## Tuning parameter 'intercept' was held constant at a value of TRUE
rfClasses <- predict(fit, newdata = test) %>% round %>% as.integer

rm(idx, train, test)

liczbę atomów

Posiadam ok 1mln przykładów podzielonych na n klas

n = data %>% select(local_res_atom_non_h_count) %>% distinct() %>% count()
n
## # A tibble: 1 x 1
##       n
##   <int>
## 1    64

Zbiór testowy złożony z 1% tych danych powinien być wystarczający. Każda z klas będzie miała więc ok. k przykładów (zależnie od rozkładu)

k = nrow(data) * 0.01 / n
k
##          n
## 1 174.5094
idx <- createDataPartition(data$local_res_atom_non_h_count, p=0.01, list=F, times = 1)
test <- data.frame(data[idx,]) %>% select(-res_name, -local_res_atom_non_h_electron_sum)
train <- data.frame(data[-idx,]) %>% select(-res_name, -local_res_atom_non_h_electron_sum)

ctrl <- trainControl(
    method = "boot", number = 20)

fit <- train(local_res_atom_non_h_count ~ .,
             data = train,
             method = "lm",
             trControl = ctrl,
             metric = "Rsquared",
             maximize = TRUE)

fit
## Linear Regression 
## 
## 1105691 samples
##     120 predictor
## 
## No pre-processing
## Resampling: Bootstrapped (20 reps) 
## Summary of sample sizes: 1105691, 1105691, 1105691, 1105691, 1105691, 1105691, ... 
## Resampling results:
## 
##   RMSE      Rsquared   MAE     
##   9.454652  0.4915068  5.385424
## 
## Tuning parameter 'intercept' was held constant at a value of TRUE
rfClasses <- predict(fit, newdata = test)

rm(idx, train, test)

15. Sekcję próbującą stworzyć klasyfikator przewidujący wartość atrybutu res_name

Posiadam ok 1mln przykładów podzielonych na 50 klas Zbiór testowy złożony z 1% tych danych powinien być wystarczający. Każda z klas będzie miała więc ok. k przykładów (zależnie od rozkładu)

k = nrow(data) * 0.01 / 50
k
## [1] 223.372
data$res_name <- as.factor(data$res_name)

idx <- createDataPartition(data$res_name, p=0.03, list=F, times = 1)
test <- data.frame(data[idx,]) %>% select(-local_res_atom_non_h_electron_sum, -local_res_atom_non_h_count)
train <- data.frame(data[-idx,]) %>% select(-local_res_atom_non_h_electron_sum, -local_res_atom_non_h_count)

ctrl <- trainControl(
    method = "boot", number = 5)

fit <- train(res_name ~ .,
             data = train,
             method = "rf",
             trControl = ctrl,
             ntree = 10,
             metric = "Accuracy",
             maximize = TRUE
             )

fit
## Random Forest 
## 
## 1083330 samples
##     120 predictor
##      50 classes: '1PE', 'ACT', 'ACY', 'ADP', 'ATP', 'BR', 'CA', 'CD', 'CL', 'CLA', 'COA', 'CU', 'DMS', 'EDO', 'EPE', 'FAD', 'FE', 'FE2', 'FMN', 'FMT', 'GDP', 'GOL', 'HEC', 'HEM', 'IOD', 'K', 'MAN', 'MES', 'MG', 'MLY', 'MN', 'MPD', 'NA', 'NAD', 'NAG', 'NAP', 'NDP', 'NI', 'NO3', 'PEG', 'PG4', 'PGE', 'PLP', 'PO4', 'SAH', 'SEP', 'SF4', 'SO4', 'TRS', 'ZN' 
## 
## No pre-processing
## Resampling: Bootstrapped (5 reps) 
## Summary of sample sizes: 1083330, 1083330, 1083330, 1083330, 1083330 
## Resampling results across tuning parameters:
## 
##   mtry  Accuracy   Kappa    
##     2   0.4176165  0.3675355
##    61   0.5322573  0.4937032
##   121   0.5429344  0.5057937
## 
## Accuracy was used to select the optimal model using the largest value.
## The final value used for the model was mtry = 121.
rfClasses <- predict(fit, newdata = test)
confusionMatrix(data = rfClasses, test$res_name)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  1PE  ACT  ACY  ADP  ATP   BR   CA   CD   CL  CLA  COA   CU
##        1PE   63    1    0    0    0    0    2    0    0    2    0    0
##        ACT    2  225    6    1    0    2    6    4   10    0    1    2
##        ACY    0    1   31    0    0    0    0    0    1    0    0    0
##        ADP    1    0    0  211   17    0    1    0    0    0    0    0
##        ATP    0    0    0    8  127    0    0    0    0    0    0    0
##        BR     0    0    1    0    0   68    2    0    2    0    0    0
##        CA     1    4    8    3    0   17 1212   23   51    1    1   15
##        CD     0    1    2    0    0    2    3  142    2    0    0    4
##        CL     2   23    2    4    0   30  114    6 1375    0    3    4
##        CLA    0    0    0    1    0    0    2    0    1  290    0    0
##        COA    0    0    0    1    0    0    2    0    1    1   71    0
##        CU     0    0    0    0    0    0    0    1    0    0    0   82
##        DMS    1    7    0    0    0    1   10    0   11    1    5    0
##        EDO   29  126   26    6    7   16   28    6   86    4   15    0
##        EPE    0    1    0    0    0    0    1    0    1    0    0    0
##        FAD    0    0    0    1    1    0    0    0    0    1    4    1
##        FE     0    0    0    0    0    0    6    0    0    0    0    1
##        FE2    0    0    0    0    0    0    4    2    0    0    0    1
##        FMN    0    0    0    1    1    0    0    0    1    0    1    0
##        FMT    0    4    3    0    0    0    0    0    3    0    0    0
##        GDP    0    0    0    7    4    0    0    0    0    0    1    0
##        GOL   32  130   28   10    5    9   64    9  120    5   27    3
##        HEC    0    0    0    0    0    0    1    0    1    0    0    0
##        HEM    0    3    0    4    3    1    2    2    7    0    0    0
##        IOD    0    1    0    0    0    8   18   10   12    0    2    0
##        K      0    1    0    0    0    7    8    0   11    0    0    0
##        MAN    0    0    0    1    0    0    1    0    5    0    1    0
##        MES    0    2    0    1    0    0    1    0    2    0    0    0
##        MG     1    7    1    3    3    2   36    1   27    1    0    2
##        MLY    3    1    0    1    1    0    1    1    0    0    2    0
##        MN     0    1    0    3    0    1   11    3    2    0    0    2
##        MPD    0    3    0    0    0    0    3    0    1    0    2    0
##        NA     0    1    0    3    0    3   26    2   45    1    0    0
##        NAD    0    0    0    7    2    0    0    1    1    1    9    0
##        NAG   23   16    2   34   20    1   34    4   27   29   21    2
##        NAP    0    0    0    0    0    0    0    0    0    0    2    0
##        NDP    0    0    0    1    0    0    1    0    0    1    1    1
##        NI     0    0    0    0    1    0    1    1    0    0    0    0
##        NO3    0    0    0    0    0    0    1    0    0    0    0    0
##        PEG    5    4    0    0    1    0    5    0    6    4    1    0
##        PG4    8    0    0    0    0    0    2    0    0    0    0    0
##        PGE    2    0    0    0    1    0    1    1    1    0    0    0
##        PLP    0    0    0    1    0    0    0    0    0    0    1    0
##        PO4    2    9    0    1    2    0   13    3   10    1    1    2
##        SAH    0    0    0    2    2    0    0    0    1    1    2    0
##        SEP    0    0    0    0    1    0    2    0    1    0    0    0
##        SF4    0    0    0    0    0    0    0    0    0    0    0    1
##        SO4    8  135   29   20    3   21  194   34  234    4   15   13
##        TRS    0    1    0    0    0    0    0    0    1    0    0    0
##        ZN     1    4    4    2    2    2   62   35   13    1    1   76
##           Reference
## Prediction  DMS  EDO  EPE  FAD   FE  FE2  FMN  FMT  GDP  GOL  HEC  HEM
##        1PE    0    2    1    0    0    0    0    0    0    7    0    0
##        ACT   13   35    0    0    2    0    1    8    0   50    0   12
##        ACY    0    4    1    0    0    0    0    1    0    5    0    1
##        ADP    0    0    1    8    0    0    3    0   13    2    0    1
##        ATP    0    1    0    2    0    0    2    0    6    1    1    2
##        BR     0    0    0    0    0    0    0    0    0    0    0    0
##        CA    10   18    5    2   13   23    1    5    0   15    4    8
##        CD     0    1    0    0    3    1    0    1    0    1    1    0
##        CL    16   77    6    2    7    5    0   12    1   61    2    9
##        CLA    0    1    1    2    0    0    0    0    0    0    0    4
##        COA    1    2    0    0    0    0    0    0    0    3    0    1
##        CU     0    1    0    0    1    2    0    0    0    0    0    0
##        DMS  312   12    2    0    0    1    1    3    0   11    0    1
##        EDO   24 1716   19    1    5    4    7   56    2  513    4   35
##        EPE    1    1   42    0    0    0    0    0    0    0    0    0
##        FAD    0    0    0  299    0    0    7    0    1    2    0    0
##        FE     0    0    0    0   39    0    0    0    0    0    0    2
##        FE2    0    1    0    0    3   43    0    0    0    1    0    2
##        FMN    0    0    0    2    0    0  108    0    1    0    1    1
##        FMT    0    6    1    0    0    1    0   79    0    9    0    1
##        GDP    0    0    1    5    0    0    0    0   96    0    0    0
##        GOL   43  484   31   10    8   10    9   58    2 2263   21   42
##        HEC    0    1    0    0    0    0    0    0    0    1  101   10
##        HEM    0    5    0    5    1    1    1    0    2    9   21  751
##        IOD    6    6    0    0    1    0    1    1    0    5    0    3
##        K      0    2    1    0    0    0    0    0    0    4    0    2
##        MAN    1    2    1    0    0    0    0    0    0    4    0    1
##        MES    0    2    3    0    0    0    1    1    0    5    0    1
##        MG     4   20    3    0    4    2    0    4    0   38    0    4
##        MLY    1    7    2    3    0    0    1    0    0   13    0    0
##        MN     1    1    0    1    1    2    0    0    0    2    0    1
##        MPD    1    5    0    0    0    0    0    1    0   11    0    1
##        NA     3   27    1    1    1    1    0    1    1   33    1    1
##        NAD    0    0    0    4    0    0    4    1    0    1    0    2
##        NAG    9   51    5   33    2    2   19    5    7  117    2   19
##        NAP    0    0    0    4    0    0    1    0    3    3    0    0
##        NDP    0    1    0    6    0    0    1    0    0    2    0    0
##        NI     0    0    0    0    1    0    0    0    0    0    0    0
##        NO3    4    2    1    0    0    0    0    1    1    3    0    2
##        PEG    1    6    2    0    0    0    1    1    0   16    1    2
##        PG4    0    5    2    0    0    0    0    1    0    7    0    1
##        PGE    1    4    0    0    0    0    0    0    0    3    0    0
##        PLP    0    1    4    1    0    0    0    0    0    1    0    0
##        PO4    2    7    3    1    2    3    4    0    1   17    1    1
##        SAH    0    0    0    2    0    0    0    0    1    0    0    0
##        SEP    0    0    0    2    0    0    0    0    1    1    0    0
##        SF4    0    0    0    0    0    0    0    0    0    0    0    0
##        SO4  134  154   31    7   22   17   10   15    3  291    8   58
##        TRS    0    1    0    1    0    0    0    0    0    4    0    1
##        ZN     3   13    0    2   28   23    2    1    0   13    1    3
##           Reference
## Prediction  IOD    K  MAN  MES   MG  MLY   MN  MPD   NA  NAD  NAG  NAP
##        1PE    0    0    1    0    0    0    0    0    1    1    4    3
##        ACT    1    3    0    3    8    1    3    5    7    4   12    5
##        ACY    1    0    0    0    0    0    0    0    0    0    0    0
##        ADP    0    0    0    1    1    1    1    0    0    7    5    1
##        ATP    0    0    0    0    1    0    0    0    0    5    1    1
##        BR     3    0    0    0    0    0    0    0    1    0    0    0
##        CA    23   43    1    3   66    3   46    2   43    2   15    2
##        CD     8    0    0    0    0    0    4    0    1    0    0    0
##        CL    33   97    3    3   61    0   13    3  157    5   16    6
##        CLA    0    1    2    0    0    0    0    0    0    2    9    0
##        COA    0    1    1    0    0    1    0    0    1    2    4    1
##        CU     0    1    0    1    0    0    1    0    0    1    0    0
##        DMS    0    1    3    3    6    1    2    3    3    2    2    1
##        EDO   20   11   22   21   66   29    6   30   76   15   99   15
##        EPE    1    1    0    5    0    2    1    0    0    1    2    0
##        FAD    0    0    0    0    0    2    0    0    1   10    6    2
##        FE     0    0    0    0    0    0    2    0    0    0    0    0
##        FE2    0    2    0    0    1    0    1    0    0    1    0    0
##        FMN    0    0    0    0    0    0    0    0    1    1    3    2
##        FMT    2    0    0    0    3    0    0    1    1    0    0    0
##        GDP    0    0    0    0    0    0    0    0    0    1    1    0
##        GOL   11   13   33   30  103   49   12   92   95   31  183   18
##        HEC    0    0    1    0    1    0    0    0    0    0    1    0
##        HEM    5    1    1    0    4    2    0    1    6    3    6    2
##        IOD  364    8    1    1    2    0    0    0    2    0    2    0
##        K      3  161    0    0    4    0    0    1    6    0    1    0
##        MAN    0    0   69    2    0    0    0    1    0    0   19    0
##        MES    2    2    0   85    2    0    2    0    1    1    1    0
##        MG     2   11    4    8  671    8   10    9   34    3    7    2
##        MLY    0    1    2    0    6  147    1    4    1    2    4    1
##        MN     3    0    1    0    6    0  143    0    1    0    3    0
##        MPD    1    0    5    0    3    1    0   53    0    1    4    0
##        NA     4    7    0    0   26    2    6    1  311    0    3    0
##        NAD    0    0    3    0    0    0    0    0    0  214    6   16
##        NAG    3   13   55    9   50   22   10   15   13   38 1689   23
##        NAP    0    0    0    0    0    0    0    0    0   10    4  179
##        NDP    0    0    1    1    0    0    0    0    0    3    1    8
##        NI     0    0    0    0    0    0    1    0    1    0    0    0
##        NO3    0    0    0    2    0    1    0    0    0    0    1    0
##        PEG    1    1    1    1    5    0    0    1    2    2   13    2
##        PG4    0    0    1    3    0    0    0    0    1    2    4    1
##        PGE    0    0    0    0    1    1    2    0    0    1    2    0
##        PLP    0    0    0    0    0    0    0    0    0    2    0    0
##        PO4    4    4    3    3   11    1    3    5    8    2    6    0
##        SAH    0    0    0    0    0    0    0    0    0    3    3    1
##        SEP    1    1    0    0    0    1    0    0    0    1    1    0
##        SF4    0    0    0    0    0    0    0    0    0    0    0    0
##        SO4   55   27   11   53  156   28   61   52   74   15   79   19
##        TRS    0    0    3    0    4    1    1    2    0    0    1    0
##        ZN    16    9    3    1   31    1   45    2    5    3    8    0
##           Reference
## Prediction  NDP   NI  NO3  PEG  PG4  PGE  PLP  PO4  SAH  SEP  SF4  SO4
##        1PE    1    0    0    2    8    5    0    0    0    0    0    2
##        ACT    2    1    6    6    3    1    0   10    3    1    0   45
##        ACY    0    0    0    0    0    0    0    1    0    0    0    2
##        ADP    2    0    0    1    2    0    1    2    6    1    0    3
##        ATP    0    0    0    1    0    1    0    0    1    0    0    0
##        BR     0    0    0    0    0    0    0    0    0    0    0    2
##        CA     2   13    2    5    0    0    2   25    1    2    0   85
##        CD     0    4    0    0    0    0    0    1    0    0    0    4
##        CL     3    5    0   10    3    3    1   19    1    1    1  101
##        CLA    3    0    0    1    0    0    0    0    0    0    0    3
##        COA    0    1    0    1    1    0    0    0    1    0    0    1
##        CU     0    1    0    0    0    0    0    1    0    0    0    0
##        DMS    1    0    2    0    1    2    1    6    0    0    0   34
##        EDO    8    0   19   78   47   30    4   24    2    2    0  188
##        EPE    0    0    0    0    0    0    1    2    2    1    0    1
##        FAD    2    0    0    2    1    1    0    1    0    1    0    0
##        FE     0    1    0    0    0    0    0    0    0    0    0    0
##        FE2    0    2    0    0    0    0    1    0    0    0    0    1
##        FMN    1    1    0    0    0    0    1    0    0    0    0    1
##        FMT    1    0    2    0    0    0    1    1    0    0    0    3
##        GDP    1    0    0    0    0    1    0    1    0    0    0    2
##        GOL    7    7   11  135   70   40    7   75    5    7    1  253
##        HEC    0    0    0    0    0    0    0    0    0    0    0    0
##        HEM    1    0    2    1    0    3    0    2    1    0    0   17
##        IOD    0    3    0    1    0    0    0    3    0    1    1   20
##        K      0    0    0    2    0    0    0    0    0    0    0    8
##        MAN    0    0    0    1    1    1    0    0    0    2    0    2
##        MES    1    1    0    0    0    0    1    5    0    0    0    4
##        MG     1    2    1    1    1    1    0    8    0    1    0   59
##        MLY    1    0    0    2    0    2    1    5    0    4    0    5
##        MN     0    2    0    0    2    1    0    4    0    1    0    6
##        MPD    0    0    1    4    0    1    0    1    1    1    0   10
##        NA     1    1    2    4    1    1    0    1    4    0    0   11
##        NAD   11    0    0    0    2    1    0    2    3    0    0    1
##        NAG   12    2    6   32   25   19    4   23   11    9    0   86
##        NAP   17    0    0    1    0    0    1    0    0    0    0    1
##        NDP   95    0    0    0    1    0    0    2    1    0    0    0
##        NI     0   35    0    1    0    0    0    0    0    0    0    2
##        NO3    0    0   55    0    1    0    0    1    0    0    0    1
##        PEG    0    1    1   86    3    6    0    3    0    0    0    4
##        PG4    0    0    0    4   48    1    0    1    0    0    0    4
##        PGE    0    0    1    5    1   28    0    0    0    0    0    4
##        PLP    0    0    0    0    0    0   96    0    0    0    0    3
##        PO4    1    2    1    0    1    1    3  302    1    2    0   86
##        SAH    0    0    0    0    0    0    0    0   91    0    0    0
##        SEP    1    0    0    0    0    0    0    1    1   73    0    0
##        SF4    0    0    0    0    0    0    0    0    0    0  143    0
##        SO4   11   29   30   35   14   15   17  444    5   17    3 3938
##        TRS    0    0    0    0    1    0    0    0    0    0    0    0
##        ZN     0   33    0    5    1    0    0   12    1    5    0   40
##           Reference
## Prediction  TRS   ZN
##        1PE    1    0
##        ACT    1    5
##        ACY    0    1
##        ADP    0    1
##        ATP    0    0
##        BR     0    0
##        CA     3  115
##        CD     0   17
##        CL     2   29
##        CLA    0    0
##        COA    0    0
##        CU     0   21
##        DMS    0    5
##        EDO   17   13
##        EPE    0    0
##        FAD    0    0
##        FE     0    2
##        FE2    0    4
##        FMN    0    1
##        FMT    0    2
##        GDP    0    1
##        GOL   45   37
##        HEC    0    0
##        HEM    0    7
##        IOD    0   13
##        K      1    7
##        MAN    1    2
##        MES    0    2
##        MG     4   27
##        MLY    1    5
##        MN     2   20
##        MPD    2    0
##        NA     0    4
##        NAD    0    2
##        NAG    7   35
##        NAP    0    1
##        NDP    0    0
##        NI     0    8
##        NO3    0    1
##        PEG    0    0
##        PG4    2    0
##        PGE    0    0
##        PLP    0    2
##        PO4    1   16
##        SAH    0    2
##        SEP    0    2
##        SF4    0    0
##        SO4   12  118
##        TRS   43    0
##        ZN     2 1244
## 
## Overall Statistics
##                                          
##                Accuracy : 0.5997         
##                  95% CI : (0.5945, 0.605)
##     No Information Rate : 0.1504         
##     P-Value [Acc > NIR] : < 2.2e-16      
##                                          
##                   Kappa : 0.5674         
##  Mcnemar's Test P-Value : NA             
## 
## Statistics by Class:
## 
##                      Class: 1PE Class: ACT Class: ACY Class: ADP
## Sensitivity            0.342391    0.31601  0.2167832   0.624260
## Specificity            0.998681    0.99113  0.9994309   0.997499
## Pos Pred Value         0.588785    0.43605  0.6200000   0.717687
## Neg Pred Value         0.996380    0.98525  0.9966547   0.996179
## Prevalence             0.005488    0.02123  0.0042648   0.010081
## Detection Rate         0.001879    0.00671  0.0009245   0.006293
## Detection Prevalence   0.003191    0.01539  0.0014912   0.008768
## Balanced Accuracy      0.670536    0.65357  0.6081071   0.810880
##                      Class: ATP Class: BR Class: CA Class: CD Class: CL
## Sensitivity            0.622549  0.356021   0.64434  0.487973   0.66329
## Specificity            0.998980  0.999670   0.97687  0.998165   0.96942
## Pos Pred Value         0.788820  0.860759   0.62346  0.699507   0.58836
## Neg Pred Value         0.997692  0.996323   0.97882  0.995529   0.97762
## Prevalence             0.006084  0.005696   0.05610  0.008679   0.06183
## Detection Rate         0.003788  0.002028   0.03615  0.004235   0.04101
## Detection Prevalence   0.004802  0.002356   0.05798  0.006054   0.06970
## Balanced Accuracy      0.810764  0.677845   0.81060  0.743069   0.81635
##                      Class: CLA Class: COA Class: CU Class: DMS Class: EDO
## Sensitivity            0.830946   0.373684  0.386792   0.527919    0.63911
## Specificity            0.999005   0.999160  0.999040   0.995568    0.93967
## Pos Pred Value         0.897833   0.717172  0.719298   0.681223    0.47973
## Neg Pred Value         0.998223   0.996440  0.996110   0.991564    0.96765
## Prevalence             0.010409   0.005667  0.006323   0.017626    0.08008
## Detection Rate         0.008649   0.002118  0.002446   0.009305    0.05118
## Detection Prevalence   0.009633   0.002953  0.003400   0.013659    0.10668
## Balanced Accuracy      0.914976   0.686422  0.692916   0.761743    0.78939
##                      Class: EPE Class: FAD Class: FE Class: FE2 Class: FMN
## Sensitivity            0.247059   0.736453  0.270833   0.304965   0.583784
## Specificity            0.999251   0.998581  0.999581   0.999191   0.999370
## Pos Pred Value         0.626866   0.864162  0.735849   0.614286   0.837209
## Neg Pred Value         0.996175   0.996776  0.996864   0.997071   0.997695
## Prevalence             0.005070   0.012109  0.004295   0.004205   0.005517
## Detection Rate         0.001253   0.008917  0.001163   0.001282   0.003221
## Detection Prevalence   0.001998   0.010319  0.001581   0.002088   0.003847
## Balanced Accuracy      0.623155   0.867517  0.635207   0.652078   0.791577
##                      Class: FMT Class: GDP Class: GOL Class: HEC
## Sensitivity            0.308594   0.676056    0.63782   0.594118
## Specificity            0.998648   0.999221    0.91562   0.999490
## Pos Pred Value         0.637097   0.786885    0.47215   0.855932
## Neg Pred Value         0.994702   0.998623    0.95528   0.997935
## Prevalence             0.007635   0.004235    0.10582   0.005070
## Detection Rate         0.002356   0.002863    0.06749   0.003012
## Detection Prevalence   0.003698   0.003639    0.14295   0.003519
## Balanced Accuracy      0.653621   0.837639    0.77672   0.796804
##                      Class: HEM Class: IOD Class: K Class: MAN Class: MES
## Sensitivity             0.76166    0.64198 0.383333   0.298701   0.355649
## Specificity             0.99594    0.99600 0.997916   0.998528   0.998678
## Pos Pred Value          0.85051    0.73387 0.700000   0.584746   0.658915
## Neg Pred Value          0.99280    0.99385 0.992222   0.995151   0.995389
## Prevalence              0.02941    0.01691 0.012526   0.006889   0.007128
## Detection Rate          0.02240    0.01086 0.004802   0.002058   0.002535
## Detection Prevalence    0.02633    0.01479 0.006860   0.003519   0.003847
## Balanced Accuracy       0.87880    0.81899 0.690625   0.648615   0.677163
##                      Class: MG Class: MLY Class: MN Class: MPD Class: NA
## Sensitivity            0.51655   0.481967  0.379310   0.187279  0.364169
## Specificity            0.98861   0.997442  0.997466   0.998075  0.992931
## Pos Pred Value         0.64644   0.633621  0.629956   0.452991  0.573801
## Neg Pred Value         0.98067   0.995255  0.992974   0.993116  0.983539
## Prevalence             0.03874   0.009096  0.011244   0.008440  0.025470
## Detection Rate         0.02001   0.004384  0.004265   0.001581  0.009275
## Detection Prevalence   0.03096   0.006919  0.006770   0.003489  0.016165
## Balanced Accuracy      0.75258   0.739704  0.688388   0.592677  0.678550
##                      Class: NAD Class: NAG Class: NAP Class: NDP Class: NI
## Sensitivity            0.539043    0.75706   0.575563   0.508021  0.238095
## Specificity            0.997585    0.96786   0.998555   0.999010  0.999491
## Pos Pred Value         0.727891    0.62672   0.788546   0.742187  0.673077
## Neg Pred Value         0.994494    0.98242   0.996036   0.997246  0.996655
## Prevalence             0.011840    0.06654   0.009275   0.005577  0.004384
## Detection Rate         0.006382    0.05037   0.005339   0.002833  0.001044
## Detection Prevalence   0.008768    0.08038   0.006770   0.003817  0.001551
## Balanced Accuracy      0.768314    0.86246   0.787059   0.753516  0.618793
##                      Class: NO3 Class: PEG Class: PG4 Class: PGE
## Sensitivity            0.387324   0.201405   0.200837  0.1696970
## Specificity            0.999311   0.996888   0.998498  0.9990409
## Pos Pred Value         0.705128   0.455026   0.489796  0.4666667
## Neg Pred Value         0.997399   0.989772   0.994287  0.9959068
## Prevalence             0.004235   0.012735   0.007128  0.0049210
## Detection Rate         0.001640   0.002565   0.001432  0.0008351
## Detection Prevalence   0.002326   0.005637   0.002923  0.0017894
## Balanced Accuracy      0.693318   0.599147   0.599667  0.5843689
##                      Class: PLP Class: PO4 Class: SAH Class: SEP
## Sensitivity            0.671329   0.305359   0.640845   0.553030
## Specificity            0.999521   0.992287   0.999401   0.999461
## Pos Pred Value         0.857143   0.546112   0.819820   0.802198
## Neg Pred Value         0.998594   0.979167   0.998474   0.998236
## Prevalence             0.004265   0.029496   0.004235   0.003937
## Detection Rate         0.002863   0.009007   0.002714   0.002177
## Detection Prevalence   0.003340   0.016493   0.003310   0.002714
## Balanced Accuracy      0.835425   0.648823   0.820123   0.776246
##                      Class: SF4 Class: SO4 Class: TRS Class: ZN
## Sensitivity            0.959732     0.7809   0.292517   0.70203
## Specificity            0.999970     0.9003   0.999341   0.98378
## Pos Pred Value         0.993056     0.5810   0.661538   0.70722
## Neg Pred Value         0.999820     0.9587   0.996892   0.98338
## Prevalence             0.004444     0.1504   0.004384   0.05285
## Detection Rate         0.004265     0.1174   0.001282   0.03710
## Detection Prevalence   0.004295     0.2021   0.001939   0.05246
## Balanced Accuracy      0.979851     0.8406   0.645929   0.84291
rm(idx, train, test)